package org.slg.oracleproject.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

/**
 * 合并核心安全配置：包含WebSecurity和MethodSecurity
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity // 启用@PreAuthorize注解
public class SecurityConfig {

    @Autowired
    private CustomAccessDeniedHandler accessDeniedHandler;

    @Autowired
    private CustomPermissionEvaluator permissionEvaluator;

    @Autowired
    private JwtAuthenticationFilter jwtFilter; // 确保注入了JWT过滤器

    // 1. 定义CorsConfigurationSource（动态设置允许的来源）
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        return new CorsConfigurationSource() {
            @Override
            public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
                CorsConfiguration config = new CorsConfiguration();

                // 动态读取请求的Origin头（前端来源）
                String origin = request.getHeader("Origin");
                if (origin != null) {
                    config.setAllowedOrigins(Collections.singletonList(origin)); // 允许当前请求的来源
                }

                // 允许的请求头（包含Authorization）
                config.setAllowedHeaders(Collections.singletonList("*"));
                // 允许的请求方法
                config.setAllowedMethods(Collections.singletonList("*"));
                // 允许携带凭证（Token/Cookie）
                config.setAllowCredentials(true);
                // 预检请求缓存时间
                config.setMaxAge(3600L);

                return config;
            }
        };
    }

    // 2. 定义CorsFilter（使用上面的CorsConfigurationSource，确保类型为CorsFilter）
    @Bean
    public CorsFilter corsFilter() {
        return new CorsFilter(corsConfigurationSource()); // 这里返回的是Spring的CorsFilter类型
    }


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtFilter) throws Exception {
        http
                .cors(cors -> cors.configurationSource(corsConfigurationSource())) // 关联跨域配置
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers(
                                "/auth/login",
                                "/doc.html", "/webjars/**", "/v3/api-docs/**",
                                "/swagger-ui/**", "/swagger-ui.html", "/favicon.ico"
                        ).permitAll()
                        .anyRequest().authenticated()
                )
                .exceptionHandling(ex -> ex
                        // 权限不足：抛出AccessDeniedException，由GlobalExceptionHandler处理
                        .accessDeniedHandler((req, res, e) -> {
                            throw new AccessDeniedException(e.getMessage());
                        })
                        // 未认证：抛出AuthenticationException，由GlobalExceptionHandler处理
                        .authenticationEntryPoint((req, res, e) -> {
                            throw new AuthenticationException(e.getMessage()) {};
                        })
                )
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
        DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
        handler.setPermissionEvaluator(permissionEvaluator);
        return handler;
    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}